package com.example.service;

import com.example.dto.AdminLoginDTO;
import com.example.dto.AdminProfileDTO;
import com.example.dto.ChangePasswordDTO;
import com.example.entity.Admin;
import com.example.repository.AdminRepository;
import com.example.utils.JwtUtils;
import lombok.RequiredArgsConstructor;
import lombok.extern.slf4j.Slf4j;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.*;

/**
 * 管理员服务
 */
@Slf4j
@Service
@RequiredArgsConstructor
public class AdminService {

    private final AdminRepository adminRepository;
    private final PasswordEncoder passwordEncoder;
    private final JwtUtils jwtUtils;

    /**
     * 管理员登录
     */
    @Transactional
    public Map<String, Object> login(AdminLoginDTO loginDTO, String clientIp) {
        // 查找管理员
        Admin admin = adminRepository.findByUsernameOrPhone(loginDTO.getUsername(), loginDTO.getUsername())
                .orElseThrow(() -> new com.example.exception.BusinessException(com.example.common.ResultCode.PASSWORD_ERROR));

        // 检查状态
        if (admin.getStatus() != Admin.AdminStatus.ACTIVE) {
            throw new com.example.exception.BusinessException(com.example.common.ResultCode.ADMIN_DISABLED);
        }

        // 验证密码
        if (!passwordEncoder.matches(loginDTO.getPassword(), admin.getPassword())) {
            throw new com.example.exception.BusinessException(com.example.common.ResultCode.PASSWORD_ERROR);
        }

        // 更新登录信息
        admin.setLastLoginTime(LocalDateTime.now());
        admin.setLastLoginIp(clientIp);
        adminRepository.save(admin);

        // 生成JWT令牌
        String token = jwtUtils.generateToken(admin.getUsername(), admin.getId(), "ADMIN");

        // 返回登录结果
        Map<String, Object> result = new HashMap<>();
        result.put("token", token);
        result.put("admin", convertToProfileDTO(admin));
        result.put("permissions", admin.getPermissionList());

        return result;
    }

    /**
     * 管理员退出登录
     */
    public void logout(Long adminId) {
        // 这里可以实现token黑名单等逻辑
        log.info("管理员退出登录: {}", adminId);
    }

    /**
     * 获取管理员信息
     */
    public AdminProfileDTO getProfile(Long adminId) {
        Admin admin = adminRepository.findById(adminId)
                .orElseThrow(() -> new com.example.exception.BusinessException(com.example.common.ResultCode.ADMIN_NOT_FOUND));
        return convertToProfileDTO(admin);
    }

    /**
     * 更新管理员信息
     */
    @Transactional
    public void updateProfile(Long adminId, AdminProfileDTO profileDTO) {
        Admin admin = adminRepository.findById(adminId)
                .orElseThrow(() -> new com.example.exception.BusinessException(com.example.common.ResultCode.ADMIN_NOT_FOUND));

        admin.setRealName(profileDTO.getRealName());
        admin.setEmail(profileDTO.getEmail());
        admin.setAvatar(profileDTO.getAvatar());

        adminRepository.save(admin);
    }

    /**
     * 修改密码
     */
    @Transactional
    public void changePassword(Long adminId, ChangePasswordDTO changePasswordDTO) {
        Admin admin = adminRepository.findById(adminId)
                .orElseThrow(() -> new com.example.exception.BusinessException(com.example.common.ResultCode.ADMIN_NOT_FOUND));

        // 验证两次密码是否一致
        if (!changePasswordDTO.isPasswordMatch()) {
            throw new com.example.exception.BusinessException(com.example.common.ResultCode.PASSWORD_NOT_MATCH);
        }

        // 验证原密码
        if (!passwordEncoder.matches(changePasswordDTO.getOldPassword(), admin.getPassword())) {
            throw new com.example.exception.BusinessException(com.example.common.ResultCode.OLD_PASSWORD_ERROR);
        }

        // 设置新密码
        admin.setPassword(passwordEncoder.encode(changePasswordDTO.getNewPassword()));
        adminRepository.save(admin);
    }

    /**
     * 获取管理员列表
     */
    public Page<Admin> getAdminList(Pageable pageable, String keyword, 
                                   Admin.AdminRole role, Admin.AdminStatus status) {
        Specification<Admin> spec = Specification.where(null);

        if (keyword != null && !keyword.trim().isEmpty()) {
            spec = spec.and((root, query, cb) -> 
                cb.or(
                    cb.like(root.get("username"), "%" + keyword + "%"),
                    cb.like(root.get("realName"), "%" + keyword + "%"),
                    cb.like(root.get("phone"), "%" + keyword + "%")
                )
            );
        }

        if (role != null) {
            spec = spec.and((root, query, cb) -> cb.equal(root.get("role"), role));
        }

        if (status != null) {
            spec = spec.and((root, query, cb) -> cb.equal(root.get("status"), status));
        }

        return adminRepository.findAll(spec, pageable);
    }

    /**
     * 创建管理员
     */
    @Transactional
    public void createAdmin(Admin admin, Long operatorId) {
        // 检查用户名是否存在
        if (adminRepository.existsByUsername(admin.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }

        // 检查手机号是否存在
        if (adminRepository.existsByPhone(admin.getPhone())) {
            throw new RuntimeException("手机号已存在");
        }

        // 加密密码
        admin.setPassword(passwordEncoder.encode(admin.getPassword()));
        
        // 设置默认值
        admin.setStatus(Admin.AdminStatus.ACTIVE);
        admin.setCreatedAt(LocalDateTime.now());
        admin.setUpdatedAt(LocalDateTime.now());

        adminRepository.save(admin);
    }

    /**
     * 更新管理员
     */
    @Transactional
    public void updateAdmin(Long id, Admin adminData, Long operatorId) {
        Admin admin = adminRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("管理员不存在"));

        // 检查用户名是否被其他人使用
        if (!admin.getUsername().equals(adminData.getUsername()) && 
            adminRepository.existsByUsername(adminData.getUsername())) {
            throw new RuntimeException("用户名已存在");
        }

        // 检查手机号是否被其他人使用
        if (!admin.getPhone().equals(adminData.getPhone()) && 
            adminRepository.existsByPhone(adminData.getPhone())) {
            throw new RuntimeException("手机号已存在");
        }

        // 更新信息
        admin.setUsername(adminData.getUsername());
        admin.setPhone(adminData.getPhone());
        admin.setRealName(adminData.getRealName());
        admin.setEmail(adminData.getEmail());
        admin.setRole(adminData.getRole());
        admin.setPermissions(adminData.getPermissions());
        admin.setUpdatedAt(LocalDateTime.now());

        // 如果提供了新密码，则更新密码
        if (adminData.getPassword() != null && !adminData.getPassword().isEmpty()) {
            admin.setPassword(passwordEncoder.encode(adminData.getPassword()));
        }

        adminRepository.save(admin);
    }

    /**
     * 更新管理员状态
     */
    @Transactional
    public void updateAdminStatus(Long id, Admin.AdminStatus status, Long operatorId) {
        Admin admin = adminRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("管理员不存在"));

        // 不能禁用自己
        if (id.equals(operatorId) && status == Admin.AdminStatus.INACTIVE) {
            throw new RuntimeException("不能禁用自己的账户");
        }

        admin.setStatus(status);
        admin.setUpdatedAt(LocalDateTime.now());
        adminRepository.save(admin);
    }

    /**
     * 删除管理员
     */
    @Transactional
    public void deleteAdmin(Long id, Long operatorId) {
        // 不能删除自己
        if (id.equals(operatorId)) {
            throw new RuntimeException("不能删除自己的账户");
        }

        Admin admin = adminRepository.findById(id)
                .orElseThrow(() -> new RuntimeException("管理员不存在"));

        // 不能删除超级管理员
        if (admin.getRole() == Admin.AdminRole.SUPER_ADMIN) {
            throw new RuntimeException("不能删除超级管理员");
        }

        adminRepository.deleteById(id);
    }

    /**
     * 获取所有权限
     */
    public Map<String, Object> getAllPermissions() {
        Map<String, Object> permissions = new HashMap<>();
        
        // 用户管理权限
        List<Map<String, String>> userPermissions = Arrays.asList(
            Map.of("key", "user:view", "name", "查看用户"),
            Map.of("key", "user:edit", "name", "编辑用户"),
            Map.of("key", "user:delete", "name", "删除用户")
        );
        
        // 商家管理权限
        List<Map<String, String>> merchantPermissions = Arrays.asList(
            Map.of("key", "merchant:view", "name", "查看商家"),
            Map.of("key", "merchant:edit", "name", "编辑商家"),
            Map.of("key", "merchant:delete", "name", "删除商家"),
            Map.of("key", "merchant:approve", "name", "审核商家")
        );
        
        // 订单管理权限
        List<Map<String, String>> orderPermissions = Arrays.asList(
            Map.of("key", "order:view", "name", "查看订单"),
            Map.of("key", "order:edit", "name", "编辑订单")
        );
        
        // 系统管理权限
        List<Map<String, String>> systemPermissions = Arrays.asList(
            Map.of("key", "system:config", "name", "系统配置"),
            Map.of("key", "system:log", "name", "系统日志"),
            Map.of("key", "announcement:manage", "name", "公告管理"),
            Map.of("key", "coupon:manage", "name", "优惠券管理"),
            Map.of("key", "statistics:view", "name", "数据统计")
        );
        
        permissions.put("user", userPermissions);
        permissions.put("merchant", merchantPermissions);
        permissions.put("order", orderPermissions);
        permissions.put("system", systemPermissions);
        
        return permissions;
    }

    /**
     * 获取仪表板数据
     */
    public Map<String, Object> getDashboardData(Admin admin) {
        Map<String, Object> dashboard = new HashMap<>();
        
        // 基本统计数据
        dashboard.put("totalUsers", 0); // 从用户服务获取
        dashboard.put("totalMerchants", 0); // 从商家服务获取
        dashboard.put("totalOrders", 0); // 从订单服务获取
        dashboard.put("todayRevenue", 0.0); // 从支付服务获取
        
        // 最近登录信息
        dashboard.put("lastLoginTime", admin.getLastLoginTime());
        dashboard.put("lastLoginIp", admin.getLastLoginIp());
        
        // 权限信息
        dashboard.put("role", admin.getRole());
        dashboard.put("permissions", admin.getPermissionList());
        
        return dashboard;
    }

    /**
     * 转换为DTO
     */
    private AdminProfileDTO convertToProfileDTO(Admin admin) {
        AdminProfileDTO dto = new AdminProfileDTO();
        dto.setId(admin.getId());
        dto.setUsername(admin.getUsername());
        dto.setPhone(admin.getPhone());
        dto.setRealName(admin.getRealName());
        dto.setEmail(admin.getEmail());
        dto.setAvatar(admin.getAvatar());
        dto.setRole(admin.getRole());
        dto.setStatus(admin.getStatus());
        dto.setLastLoginTime(admin.getLastLoginTime());
        dto.setLastLoginIp(admin.getLastLoginIp());
        dto.setCreatedAt(admin.getCreatedAt());
        return dto;
    }
}
